<?php

namespace App\Http\Controllers;



use Lcobucci\JWT\Builder;
use Lcobucci\JWT\Parser;
use Lcobucci\JWT\Signer\Hmac\Sha256;
use Lcobucci\JWT\ValidationData;


/**
 * 生成jwt验证
 */
class JwtController extends Controller
{
    public $config;
    public function __construct()
    {
        $this->config = config('jwt');
    }


    /**
     * 获取 jwt token
     * @param timestamp  时间戳 13位
     * @param code  appid 拼接 appsecret 拼接 时间戳  然后  md5后值 在全部转大写
     */
    public function getAuthToken()
    {
        $code = request()->code;
        $timestamp = request()->timestamp;

        $controllerObj = new Controller();
        if (empty($code) || empty($timestamp)) {
            return $controllerObj->returnApi(201, '网络错误');
        }

        //验证时间戳的有效性 允许 30s误差
        if (strtotime("-30 seconds") . '000' > $timestamp) {
            return $controllerObj->returnApi(201, '网络错误');
        }
        $token = strtoupper(md5($this->config['appid'] . $this->config['appsecret'] . $timestamp));
        // dump($token != $code);die;
        if ($token != $code) {
            $controllerObj->returnApi(201, '网络错误');
        }
        //验证成功返回token
        $data['token'] = $this->createToken($this->config['issue']);
        $data['expires_in'] = $this->config['expires_in'];
        return  $controllerObj->returnApi(200, '获取成功', true, $data);
    }

    /**
     * 生成jwt  token
     * @param null $uid
     * @return string
     * 生成token
     */
    public function createToken($uid = null)
    {
        $signer = new Sha256(); //加密规则
        $time = time(); //当前时间

        $token = (new Builder())
            ->issuedBy($this->config['issue']) //签发人
            ->canOnlyBeUsedBy($this->config['accept']) //接收人
            ->identifiedBy($this->config['title'], true) //标题id
            ->issuedAt($time) //发出令牌的时间
            ->canOnlyBeUsedAfter($time) //生效时间(即时生效)
            ->expiresAt($time + $this->config['expires_in']) //过期时间
            ->with('uid', $uid) //用户id
            ->sign($signer, $this->config['sign']) //签名
            ->getToken(); //得到token

        return (string)$token;
    }


    /**
     * 验证jwt
     * @param null $token
     * @return int|mixed
     * 验证token
     */
    public function verifyToken($token = null)
    {
        //检测是否接收到了token
        if (empty($token)) {
            return '认证失败invalid_token'; //token获取失败
        }
        //转化为可以验证的token
        $token = (new Parser())->parse((string) $token);
        //验证基本设置
        $data = new ValidationData();
        $data->setIssuer($this->config['issue']);
        $data->setAudience($this->config['accept']);
        $data->setId($this->config['title']);

        if (!$token->validate($data)) {
            return '认证失败invalid_token'; //token过期或无效
        }
        //验证签名
        $signer = new Sha256();
        if (!$token->verify($signer,  $this->config['sign'])) {
            return '签名错误invalid_token'; //签名错误
        }
        //验证通过，返回用户id
        return true;
    }
}
